package com.quwan.component;

import com.quwan.app.service.OrderService;
import com.quwan.common.ImMsgType;
import com.quwan.common.enums.RedisListenerEnum;
import com.quwan.config.yml.ImConfig;
import com.quwan.manager.service.MemberClickNumService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/**
 * @author quan
 * @date 2021-11-26 16:51
 */

@Component
@Slf4j
public class RedisKeyEventListener extends KeyExpirationEventMessageListener {
    //锁释放时间
    private static final Long auto_unLock = 5L;
    @Autowired
    private RedissonClient redisson;
    @Autowired
    private OrderService orderService;
    @Autowired
    private ComponentFactory componentFactory;
    @Autowired
    private TencentComponent tencentComponent;

    @Autowired
    private MemberClickNumService clickNumService;
    @Autowired
    private ImConfig imConfig;
    private static String pushContent = "约单的过程中,请使用文明用语,如有纠纷,低俗,色情 骚扰等请联系平台投诉处理,如果违反用户协议和隐 私政策等涉黄问题,平台查处后将封禁账号,请严格遵 相关规定!";

    public RedisKeyEventListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    /**
     * 此处定义规则 key过期 按照 RedisListenerEnum.split 分割符 获取对应key 和key后面的参数
     * key过期事件拿不到缓存时 存入的具体值 以RedisListenerEnum.split分割口第2个参数定义为业务参数
     *
     * @param message key =key@@Params
     * @param pattern
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String key = message.toString();
        if (key == null)
            return;
        String[] cancelOrder = key.split(RedisListenerEnum.split);
        if (cancelOrder.length == 2) {
            Consumer<String> instance = componentFactory.getRedisListenerProcessInstance(RedisListenerEnum.getByKey(cancelOrder[0]));
            if (instance != null)
                instance.accept(cancelOrder[1]);
        }
    }

    //统计访问次数
    public Consumer<String> autoAccessCount() {
        return _lockMethod(clickNumService::autoAccessCount);
    }

    //已支付订单 发单人超时未接单 取消该订单
    public Consumer<String> cancelNotProcessOrder() {
        return _lockMethod(orderService::cancelNotProcessTimeOutOrder);
    }

    //取消未支付优惠订单 优惠信息返还用户
    public Consumer<String> cancelTimeOutCouponOrder() {
        return _lockMethod(orderService::cancelTimeOutOrder);
    }

    //超时 自动确认订单
    public Consumer<String> autoConfirmOrder() {
        return _lockMethod((id) -> orderService.confirmOrder(orderService.getMIdByOrderId(id), id));
    }

    @Deprecated
    //用户注册自动推送系统消息
    public Consumer<String> autoPushMsg() {
        return _lockMethod((id) -> tencentComponent.batchPushMsg(2, imConfig.getAdminAcc(), Arrays.asList(id), ImMsgType.text.getCode(), pushContent));
    }

    private Consumer<String> _lockMethod(Consumer<String> instance) {
        return str -> {
            RLock lock = redisson.getLock(str + ".lock");
            try {
                //尝试加锁 无需等待 加不到锁就继续执行
                if (lock.tryLock(0, auto_unLock, TimeUnit.SECONDS))
                    instance.accept(str);
            } catch (InterruptedException e) {
                log.error("lock exp::{}", e.getMessage());
            } finally {
                if (lock.isHeldByCurrentThread())
                    lock.unlock();
            }
        };
    }


}
